Programmierung
**************

In diesem Kapitel finden vermutlich nur Programmierer Interessantes.

Was ist die beste Dokumentation für Programmierer?
==================================================

Die beste verfügbare Dokumentation sind sicherlich die RKM's (ROM Kernel Manuals, die schwarzen) von Commodore. Sie werden von Addison-Wesley veröffentlicht.

     The Amiga ROM Kernel Manual:  Libraries, ISBN 0-201-56774-1
     The Amiga ROM Kernel Manual:  Devices, ISBN 0-201-56775-X
     The Amiga ROM Kernel Manual:  Includes and Autodocs, ISBN
                                                          0-201-56773-3
     The Amiga Hardware Manual, ISBN 0-201-56776-8
     The Amiga User Interface Style Guide, ISBN 0-201-57757-7

Vor allem die Libraries sind ein Muß. Weniger nützlich sind die Includes und Autodocs: Sie sind auf Diskette als Online-Hilfe sicher nützlicher. See Include-Dateien.

AmigaDOS wird in diesen Büchern kaum behandelt. Die Autodocs geben einige Informationen, aber um tiefer einzusteigen braucht man das

     The AmigaDOS Manual, 3rd Edition, ISBN 0-553-35403-5

ebenfalls von Commodore, das von Bantam Books herausgegeben wird.

Eine gute Wahl ist auch

     The Amiga Guru Book

von Ralph Babel. Das Buch beginnt mit einem ca. 250-seitigen allgemeinen Überblick über verschiedenste Aspekte der Programmierung des Amiga. Für Anfänger dürften vor allem die Abschnitte über die Amiga-Datentypen sowie die Amiga-Includes und die amiga.lib interessant sein, aber auch Erfahrene finden hier mit Sicherheit noch Neues, was zum Teil nicht einmal in den RKM's enthalten ist. Den größten Teil des Buches nehmen aber 500 Seiten nur zu AmigaDOS ein. Dieser Teil ist meines Erachtens der wichtigste, weil das AmigaDOS-Manual der schlechteste Teil der offiziellen Dokumentation ist. Das Buch ist sehr dicht geschrieben und deshalb weniger leicht lesbar als die RKM's, aber ich empfehle es als Zusatz und vor allem anstelle des AmigaDOS-Manuals. (Allerdings ist das Guru-Buch kein Ersatz für die Libraries & Devices, die hier nicht behandelt werden.) Unglücklicherweise hat das Buch keine ISBN-Nummer und ist deshalb nur bei den folgenden Adressen erhältlich:

                                 Almathera Systems Limited
                                 Southerton House
     NBG USA, Inc.               Boundary Business Court
     482 Holly Avenue            92-94 Church Road
     St. Paul, MN 55102          Mitcham, Surrey CR4 3TD
     USA                         England
     Voice: +1 (612) 290 9447    Voice: +44 181 687 0040
     Fax:   +1 (612) 290 9449    Fax:   +44 181 687 0490
                                 E-Mail: <almathera@cix.compulink.co.uk>

                                 Stefan Ossowskis Schatztruhe
     Hirsch & Wolf OHG           Gesellschaft für Software mbH
     Mittelstraße 33             Veronikastraße 33
     D-56564 Neuwied             D-45131 Essen
     Germany                     Germany
     Voice: +49 (2631) 8399-0    Voice: +49 (201) 788778
     Fax:   +49 (2631) 8399-31   Fax:   +49 (201) 798447
                                 E-Mail: <stefano@tchest.e.eunet.de>

     Someware
     27 rue Gabriel Péri
     59186 Anor
     France
     Voice: +33 27596000
     Fax:   +33 27595206
     E-Mail: <didierj@swad.someware.com>

Für weitere Informationen empfehle ich auch die FAQ von Marc Atkins über Bücher zum Thema Amiga, die alle 4 Wochen in comp.sys.amiga.misc erscheint.

Was ist CATS?
=============

Dies ist eine Abteilung von Commodore West Chester, die früher Commodore Amiga Technical Support hieß und später in Commodore Application and Technical Support umbenannt wurde. Die Mitglieder arbeiten unabhängig von der Entwicklungsabteilung, aber eng mit ihr zusammen, und versuchen, Entwicklern außerhalb von Commodore beim Erstellen guter Amiga-Anwendungen zu helfen, sei das eine Hard- oder Software. Dazu hat CATS eine Menge an Informationen und Tools gesammelt, auf Floppy, CD oder Papier. Ein großer Teil dieses Materials ist auch der Allgemeinheit, d. h. für Nicht-Developer zugänglich. Aber bitte CATS nicht mit einer Hotline verwechseln!

Amerikaner können das Material von

         CATS
         Commodore Electronics Limited
         950 Rittenhouse Road
         Norristown, PA 19403

bekommen, der Distributor für ganz Europa ist die

         Fa. Hirsch & Wolf
         Mittelstr. 33
         56564 Neuwied
         Tel. 02631/83990

Dr. Peter Kittel, peterk@cbmger.de.so.commodore.com

Wo bekomme ich die Amiga-Include-Dateien?
=========================================

Der einzige legale Weg, die Include-Dateien und die AutoDocs zu bekommen (und Sie sollten sie bekommen, sie sind sehr nützlich!), ist, Developer zu werden (siehe Developer) oder das sogenannte NDU (Native developers update kit, auch als NDUK, NDK bekannt oder ADU für Amiga Developer Update) bei CATS zu kaufen. See CATS. Es kostet etwa 50DM, was sicher ein fairer Preis ist. Dabei handelt es sich um ein 5-Disketten-Set, das neben den aktuellen Includes und AutoDocs auch Tools für Programmierer, z.B. Enforcer, Mungwall, Sushi und die debug.libg (zum Debuggen) sowie anderes, z.B. CatComp (see Lokalisierung) oder Report (für Bug-Reports oder Vorschläge an Commodore) enthält. Die aktuelle Version ist 3.1 und für Programmierer beinahe obligatorisch.

Wem die Includes genügen, der kann diese über ein Update seines Compilers (nur kommerzielle Compiler) oder von den Fish-CDs bekommen. See Fish-CD.

Wie werde ich Developer?
========================

Um Developer zu werden, braucht man die ADSP-Antragsformulare (Amiga developer support program). Um diese zu bekommen, sollte man einen Brief an die lokale Commodore-Niederlassung schreiben und nach diesen Papieren fragen, in denen das weitere erklärt wird. In Deutschland ist die Adresse folgende:

         Commodore
         Lyoner Straße 38
         60528 Frankfurt

Es gibt drei verschiedene Arten von Developern:

Registered
     Hier bekommt man vor allem Zugang zum CBMNET (eine Art Commodore-internes Usenet), über das man direkt mit anderen Entwicklern auch von Commodore selber über seine Probleme diskutieren kann. Die Jahresgebühr beträgt 150 DM, die einmalige Aufnahmegebühr 50 DM.

Certified
     Dies ist die interessanteste Klasse: Man bekommt von der meisten Systemsoftware die aktuellen Beta-Versionen (z. B. Kickstart und Workbench) sowie die dazugehörigen Includes und AutoDocs. Certifieds bekommen aber nicht jede Beta und in der Regel auch keine Hardware-Beta. Man bezahlt 400 DM pro Jahr dafür und eine einmalige Aufnahmegebühr von 100 DM.

Commercial
     Kommerzielle Entwickler bekommen im wesentlichen dieselben Informationen wie die "Zertifizierten", allerdings kompletter, sprich auch Beta-Hardware, und etwas früher. Dies hat auch seinen Preis: 700DM pro Jahr plus einmalige Aufnahmegebühr von 100DM.

Die Preise und die angebotenen Möglichkeiten können von Land zu Land verschieden sein, auch gibt es meines Wissens nicht in allen Ländern den "Registered". Ein guter Tip ist es, eine Gruppe zu bilden und damit die Kosten zu reduzieren.

Alle Entwickler müssen Non-disclosure agreements (NDA) unterzeichnen. Diese besagen, daß sie über die erhaltenen Informationen außerhalb von speziell dazu freigegebenen Orten oder Kanälen nicht einmal zu anderen Entwicklern sprechen dürfen, so lange sie nicht die explizite Erlaubnis dazu von Commodore haben.

Was für Compiler (und Assembler) gibt es?
=========================================

Es gibt viele Programmiersprachen auf dem Amiga, kommerzielle Compiler ebenso wie frei kopierbare. Ich möchte nur diejenigen aufzählen, die mir bekannt sind oder die ich aus einem anderem Grund für erwähnenswert halte.

Assembler
     Alle C-Compiler beinhalten einen Assembler. Frei kopierbar und zuverlässig sind A68K und PhxAss. (Aminet, Directory dev/asm oder Fish-Disks 521 bzw. 906)

C
C++
     Frei kopierbare C-Compiler sind der gcc (der sein eigenes Directory dev/gcc auf dem Aminet hat) und die Probeversion (mit der man aber schon eine ganze Menge anfangen kann) von Dice (per FTP von ftp.uni-paderborn.de, Directory /news/comp.binaries.amiga/volume91/languages oder auf Fish disk 491). Der große Vorteil von gcc ist, daß man ihn auf der ganzen Welt und auf nahezu jedem Computer findet. Ein weiterer Vorteil ist, daß er sogar einen C++-Compiler enthält! Aber er ist langsam und benötigt 4MB RAM oder mehr. See Der GNU C Compiler. See Mail-Listen.

     Kommerzielle C-Compiler sind Aztec-C, Dice und SAS-C. Aztec-C wird jedoch leider nicht mehr weiterentwickelt. Was die kommerziellen Compiler auszeichnet, sind ihre hervorragenden Source-Level-Debugger, die den anderen fehlen.

     SAS hat leider angekündigt, den Amiga-Compiler nicht weiter zu unterstützen. Verkauft wird er aber noch, und da er gegenwärtig noch voll aktuell ist und sogar einen Crosscompiler von C++ in C enthält (der vom Debugger unterstützt wird), ist er meines Erachtens derzeit das beste Angebot, insbesondere zu dem äußerst günstigen Preis von 184.-DM für Studenten und Besitzer anderer Compiler. In Deutschland erhält man SAS/C bei

              SAS Institute GmbH
              Postfach 10 53 40
              69043 Heidelberg
              Deutschland

              Telefon: 06221/4160
              EMail: eurdoc2@vm.sas.com

     Dice bietet wie SAS einen Sonderpreis für Schüler und Studenten von ca. 130.-DM. Der Compiler ist stabil und vor allem sehr schnell. Der größte Nachteil von Dice ist (verglichen mit den anderen kommerziellen Compilern) der Debugger, ein sogenannter Source-Line-Debugger: Dies bedeutet, daß man den Quelltext sieht und das Programm Schritt für Schritt abarbeiten kann, aber leider nur Speicher und nicht etwa bestimmte Variablen anzeigen kann. Informationen über Dice: info@oic.COM.

     Comeau C++ ist ebenfalls ein Crosscompiler, was an und für sich kein Problem wäre. Aber Comeau C++ hat keinen integrierten C-Compiler, man braucht also zusätzlich SAS-C, Aztec-C oder Dice. Dafür ist er kompatibel zu AT&T cfront 3.0, unterstützt Exceptions und läuft wie gcc auf vielen verschiedenen Systemen. In Deutschland wird auch Maxxon C++ angeboten, über das ich nichts sagen kann. Beide Compiler sind kommerziell. Comeau's Adresse ist:

              Comeau computing
              91-34, 120th Street
              Richmond Hill, NY, 11418-3214
              USA

              EMail: Greg Comeau, comeau@bix.com

Forth
     JForth soll eine exzellente Forth-Version sein. Unter anderem enthält es objektorientierte Erweiterungen, ein volles Amiga-Interface und einen Anwendungsgenerator. Es ist erhältlich von:

              Delta Research
              P.O. Box 151051
              San Rafael, CA   94915-1051

              Phone: (415) 453-4320
              EMail: Phil Burk, phil@ntg.com
                     Mike Haas, haas@starnine.com

Fortran
     (Seufz! Es gibt immer noch Leute, die es brauchen :-<) Frei kopierbar sind BCF (Fish disk 470) und f2c, der Fortran in C-Quelltext umwandelt. (Aminet, Directory /dev/lang). Ein kommerzieller Compiler ist von ABSoft erhältlich. Allerdings sind dies alles nur Fortran-77-Compiler, es gibt keine Fortran-90-Compiler auf dem Amiga.

Lisp
     Frei kopierbare Lisp-Interpreter sind XLisp (Fish-Disk 181) und OakLisp (Fish-Disks 519 und 520) und CLISP (/pub/lisp/clisp/binaries/amiga at ma2s2.mathematik.uni-karlsruhe.de). Auch Compiler gibt es: Gambit (Fish-Disks 764 und 765) sowie Scheme-to-C (Fish-Disks 556-558). Von Interesse ist vielleicht eine Mail-Liste: Senden Sie dazu eine Mail mit dem Wort Subscribe an amigalisp@contessa.phone.net.

Prolog
     /dev/lang/UNSWProlog.lha und dev/lang/sbp3_1e auf dem Aminet sowie SBProlog auf der Fish-Disk 141 und SBProlog auf der Fish-Disk 145 sind frei kopierbare Prolog-Interpreter.

Modula-2
     M2Amiga wird in Europa und Benchmark Modula-2 in den USA angeboten. Beide sollen sehr gut sein und sowohl über gute Source-Level-Debugger als auch eine umfangreiche Bibliothek verfügen. Besonders M2Amiga wird sehr gut unterstützt durch eine deutsche Benutzergruppe (AMOK), die z.B. eine eigene PD-Serie anbieten. See Mail-Listen.

     M2Amiga bekommt man bei

              A+L AG
              Daderiz 61
              2540 Grenchen
              Schweiz

              Tel.: +41/65/52 03-11
              Fax:              -79

     und Benchmark Modula-2 ist erhältlich von:

              Armadillo Computing
              5225 Marymount Drive
              Austin, Texas 78723
              USA

              Phone/FAX: 512/926-0360.
              EMail: Jim Olinger, jolinger@bix.com

Oberon
Oberon-2
     Es gibt zwei Oberon-2-Compiler für den Amiga: AmigaOberon ist wie M2Amiga von A+L und kommerziell. Der Compiler kommt mit einer integrierten Entwicklungsumgebung (incl. freikonfigurierbarem Editor) und umfangreicher Modulbibliothek. Library Linker zum einfachen Erzeugen von AmigaOS Shared Libraries sowie Run-time Source-Level-Debugger sind ebenfalls erhältlich.

     Oberon-A ist ein Freeware-Compiler, allerdings erst in einer Beta-Version, insbesondere sind die Modulbibliotheken unvollständig. (Quelle: Aminet, Directory dev/obero). See Mail-Listen.

     Für beide Compiler gibt es Unmengen von Modulen und Bsp.-Sourcen auf AMOK-Disks.

Pascal
     Es gibt einen PD-Compiler namens PCQ (Aminet, Directory dev/lang oder Fish-Disk 511), der allerdings kein voller Pascal-Compiler ist und dem sehr wesentliche Dinge fehlen. P2C konvertiert Pascal in C und ist auf der Fish-Disk 341 zu finden. (Aminet: /dev/misc/p2c120.lha) Ferner gibt es zwei kommerzielle Compiler namens HiSoft-Pascal (von der gleichnamigen Firma) und KickPascal von Maxxon. HiSoft und P2c behaupten, kompatibel zu Turbo-Pascal 5.0 zu sein. HiSoft hat außerdem einen guten Source-Level-Debugger.

Warum funktioniert keine Esc-Sequenz?
=====================================

Viele Drucker kommen mit einem Handbuch, das erklärt, welche Esc-Sequenzen welche Funktion auslösen. Aber wenn man diese Sequenzen dann einmal ausprobiert, passieren oft merkwürdige Sachen, nämlich entweder gar nichts oder etwas ganz anderes, als geplant war. Und das hat auch einen Grund, nämlich die Amiga-Druckertreiber. Diese Treiber sind so gebaut, daß sie nur einen bestimmten Satz ANSI-Esc-Sequenzen verstehen, nicht die (verschiedenen) druckereigenen, von den verschiedenen Druckerherstellern definierten. Der Sinn dabei ist, daß jede Anwendung auf dem Amiga nur diesen einen Standardsatz an Sequenzen verwendet und so nicht zu wissen braucht, welcher Drucker tatsächlich angeschloßen ist. Der Druckertreiber übersetzt dann diese Standardsequenzen in die druckereigenen. Eine Liste der verfügbaren ANSI-Esc-Sequenzen findet sich im aktuellen Workbench-Handbuch (oder in älteren AmigaDOS-Handbüchern). Wenn Du nun eine Steuersequenz an den Drucker schicken willst, die es nicht als ANSI-Sequenz gibt, so hast Du zwei Möglichkeiten, dies doch zu erreichen:

 1. Umgeh den Druckertreiber (der erfolglos versuchen würde, die Sequenz zu interpretieren oder zu übersetzen) und sende die Ausgabe nur für die Länge dieser Sequenz an PAR: (bzw. SER:). Dabei muß man die Druckerausgabekanäle umständlich oft umschalten, und man muß wissen, wo der Drucker angeschlossen ist (PAR: oder SER:).

 2. Benutze eine spezielle ANSI-Sequenz, genau für diesen Fall gedacht:

              Esc[<n>"<x>

     wobei <n> die dezimal geschriebene Anzahl an Bytes in der Sequenz <x> ist, die gerade die spezielle Drucker-Sequenz enthält. Diese ANSI-Sequenz sagt dem Druckertreiber, daß er die nächsten <n> Bytes nicht interpretieren oder übersetzen soll.

Aber beide Methoden haben einen grossen Nachteil, wenn sie in einem Anwendungsprogramm verwendet werden: Man verliert die Druckerunabhängigkeit! Solange man sich an die ANSI-Sequenzen hält, kann man jeden Drucker der Welt ansteuern, solange es einen Amiga-Druckertreiber für ihn gibt. Wenn man anfängt, druckereigene Sequenzen zu verwenden, ist das Programm an diesen einen Druckertyp gebunden und mit keinem anderen benutzbar (oder man müßte einige dutzend neue Druckertreiber für dieses Programm erstellen).

Dr. Peter Kittel, peterk@cbmger.de.so.commodore.com

Kann ich AmigaBasic auf dem A1200 verwenden?
============================================

Letztens ging eine Kontroverse über AmigaBasic durch die Netze: Ich sagte, auf dem A1200 läuft es einigermaßen problemlos, jemand anders berichtete, daß es bei jedem kleinsten Fehler sofort komplett abstürzt, was ich nicht nachvollziehen konnte.

Jetzt kann ich es: Es liegt am Sound-Prefs-Editor. Wenn man in ihm die Sound-Ausgabe ganz abschaltet, kann man mit AmigaBasic arbeiten. Wenn hier ein Sound (z. B. Piepsen) angewählt ist, kollidiert das mit dem Sound, den AmigaBasic offensichtlich zu Fuß und nicht ganz korrekt selber erzeugen will, bumm.

Abhilfe also:

 1. Im Sound-Editor den Ton abstellen.

 2. Auf einem A4000 (oder einem A1200 mit Fast-RAM-Erweiterung (Nur bei einem zusätzlichen Prozessor)) muß man zusätzlich NoFastMem aktivieren.

 3. Möglichst SUBs vermeiden und stattdessen herkömmliche GOSUBs benutzen, dann ist die Kompatibilität zu neueren Prozessoren höher.

Dr. Peter Kittel, peterk@cbmger.de.so.commodore.co

Wie lokalisiere ich mein Programm?
==================================

Nehmen wir an, wir wollen ein HelloLocalWorld.c schreiben. Das letztendliche Programm sieht dann ungefähr so aus:

         #include "HelloLocalWorld_Cat.h"
         #include <clib/exec_protos.h>

         struct Library *LocaleBase;

         void main(int argc, char *argv[])

         {
             /* Öffne die locale.library. (Kein Abbruch, wenn sie nicht
                da ist, weil dann einfach die eingebauten Strings verwendet
                werden. Aus diesem Grund auch keine Verwendung des
                AutoOpening, auch wenn es der Compiler beherrscht.)
             */
             LocaleBase = OpenLibrary("locale.library", 38);
             OpenHelloLocalWorldCatalogs(NULL, NULL);

             printf(GetString(MSG_Hello));

             CloseHelloLocalWorldCatalog();
             if (LocaleBase) CloseLibrary(LocaleBase);
         }

Die Funktion GetString prüft, ob die gewünschten Kataloge vorhanden sind und liefert einen Zeiger auf einen String, entweder den eingebauten oder den Katalogstring. (In unserem Fall den deutschen String.)

Der Hauptunterschied zum gewohnten HelloWorld.c ist also (abgesehen von der minimalen Initialisierung und dem Gegenstück am Programmende), Strings durch einen Funktionsaufruf zu ersetzen. Man braucht also eine Datei HelloLocalWorld_Cat.c, die die Funktionen OpenHelloLocalWorld, GetString, CloseHelloLocalWorld_Cat.h und die eingebauten Strings enthält (dies könnte ein Array sein, das unter anderem

             array[MSG_Hello] = "Hello, local world.\n";

enthält) und ein Includefile HelloLocalWorld_Cat.h, das die ID's wie MSG_Hello definiert. Es ist nicht nötig zu wissen, wie diese Dateien intern arbeiten, insbesondere benötigt man auch keine Kenntnis der locale.library!

Dazu gibt es verschiedene Kataloggeneratoren (im Folgenden KG), nämlich CatComp (nur für Developer), KitCat (nur deutsche Dokumentation, was hierzulande kein Problem ist), MakeCat (das ich nicht kenne) und FlexCat (das ich empfehle, einerseits, weil es sehr flexibel im erzeugten Source ist und z.B. Lokalisierung unter 2.0 sowie beliebige Programmiersprachen unterstützt, selbst Amiga-E, Cluster, Pascal, ... und andererseits, weil es von mir ist ;-) ), die diese Dateien sowie die Kataloge erzeugen. (Der obige Quelltext könnte je nach KG leicht unterschiedlich aussehen.) Siehe Aminet, directory dev/misc.

Wie funktionieren diese KGs? Zunächst erzeugt man eine sogenannte Katalogbeschreibung (Catalog description), die so aussehen könnte:

         ; Mit einem Semikolon beginnende Zeilen sind Kommentare
         # language english
         ; die Sprache der eingebauten Strings
         # version 0
         ; die Katalogversion (0 = beliebig)
         MSG_Hello (1/15/30)
         Hello, local world

Jeder String wird durch zwei Zeilen wie die letzten beiden definiert: MSG_Hello ist die String-ID, (1/15/30) gibt den Wert der ID sowie die minimale und maximale Länge an. (Diese Argumente können auch weggelassen werden, in welchem Fall einfach die nächste freie ID verwendet wird.)

Nun schreiben wir das Programm. Sobald es fertig ist, wird mit dem KG eine sogenannte Katalogübersetzung (eine für jede andere Sprache als die eingebaute) erzeugt, die so aussehen könnte:

         ; Mit einem Semikolon beginnende Zeilen sind Kommentare
         ## language deutsch
         ; the catalog language
         ## version $VER: Deutsch.catalog 1.0 (22.12.93)
         ; the catalog files version string
         MSG_Hello

         ; Hello, local world

Beachten Sie die leere Zeile nach der String-ID! (Die Argumente von ## language und ## version wären vielleicht leer.) Hier müssten jetzt die deutschen Strings eingesetzt werden. Mit dem KG wird daraus dann der eigentliche Katalog erzeugt. (Beachten Sie auch, daß hier die Angaben über String-ID und Stringlänge fehlen: Sie werden aus der Katalogbeschreibung übernommen.

Wenn das Programm verändert wird (neue Strings, andere Längen) und die Katalogbeschreibung sich damit ebenfalls ändert, dann kann der KG analog benutzt werden, um auch die Katalogübersetzung und damit den Katalog auf den neuesten Stand zu bringen.

Wie erhält man einen Zeiger auf das Fenster einer Konsole?
==========================================================

Die folgende Funktion liefert den Window-Zeiger eines CON-Fensters. Sie kann unter allen Versionen des Amiga-OS ausgeführt werden.

       struct Window *getConWindowPtr(BPTR fh)
       {
         struct Window *w;
         struct FileHandle *cfh;
         struct StandardPacket *sp;
         struct InfoData *id;
         struct MsgPort *mp;

         w = NULL;

         if ((cfh = BADDR(fh))->fh_Type != NULL) {
           if (sp = AllocMem(sizeof (struct StandardPacket),
                            MEMF_PUBLIC | MEMF_CLEAR)) {
             if (id = AllocMem(sizeof (struct InfoData),
                              MEMF_PUBLIC | MEMF_CLEAR)) {
               if (mp = CreatePort(NULL, 0)) {
                 sp->sp_Msg.mn_Node.ln_Name = (char *) &sp->sp_Pkt;
                 sp->sp_Pkt.dp_Link         = &sp->sp_Msg;
                 sp->sp_Pkt.dp_Port         = mp;
                 sp->sp_Pkt.dp_Type         = ACTION_DISK_INFO;
                 sp->sp_Pkt.dp_Arg1         = MKBADDR(id);

                 PutMsg(cfh->fh_Type, &sp->sp_Msg);
                 (void) WaitPort(mp);
                 (void) GetMsg(mp);

                 if (sp->sp_Pkt.dp_Res1)
                   w = (struct Window *) id->id_VolumeNode;

                 DeletePort(mp);
               }
               FreeMem(id, sizeof (struct InfoData));
             }
             FreeMem(sp, sizeof (struct StandardPacket));
           }
         }

         return w;
       }

Anmerkungen:

  * Auf ein CON-Fenster direkt zuzugreifen kann Konflikte mit Aktionen des CON-Handlers hervorrufen. Seien Sie vorsichtig!

  * Um den Window-Zeiger einer CLI-Konsole zu erhalten, übergibt man ein durch Open("*", MODE_OLDFILE) gewonnenes FileHandle an obige Funktion.

  * Das Ergebnis der obigen Funktion kann sehr wohl NULL sein, etwa im Falle eines AUX-Handlers oder falls ein AUTO-CON-Handler sein Fenster nicht öffnen kann.

  * Schickt man ein ACTION_DISK_INFO-Paket an einen AUTO-CON-Handler (2.0+), so verliert dessen Fenster seine speziellen AUTO-Eigenschaften (es kann also nicht mehr durch das Betätigen des Close-Gadgets geschlossen werden), weil der in id_VolumeNode gelieferte Window-Zeiger gültig bleiben muß.

  * Alles in allem: Verwenden Sie diese Funktion nicht. :-)

Weitere Informationen finden Sie auf den Seiten 273, 276, 435, 463, 485 und 629 im "Amiga Guru Book" (see Dokumentation).

Ralph Babel, rbabel@babylon.pfm-mainz.de

Was sind Pragmas?
=================

Pragmas sind spezielle Anweisungen an den C-Compiler. Zwei Probleme entstehen bei der Verwendung von Pragmas:

 1. Pragmas sind hochgradig compilerspezifisch. Nicht einmal die Amiga-Compiler haben dieselben Pragmas, selbst wenn damit das gleiche bewirkt wird.

 2. Man kann sich nicht darauf verlassen, daß ein Compiler Pragmas ignoriert, die er nicht versteht. Dies gilt selbst dann, wenn man einen Ausdruck wie den folgenden verwendet:

              #ifndef MY_COMPILER
              #pragma DoAnything
              #endif

Das letztere Problem läßt sich umgehen, indem man Pragmas wie folgt in eigene Include-Files setzt. (Das gleiche gilt übrigens auch für Präprozessor-Kommandos wie #asm (Aztec-C) oder #extern (C++).)

         #ifndef MY_COMPUTER
         #include <mypragmas.h>
         #endif

Aber was machen Pragmas auf dem Amiga? Meistens werden sie verwendet, um dem Compiler mitzuteilen, wie gewisse Library-Funktionen aufgerufen werden. (Tatsächlich wird fast immer diese Verwendung gemeint, wenn Amiga-Besitzer über Pragmas sprechen.) Gewöhnliche C-Funktionen erwarten ihre Argumente auf dem Stack, Library-Funktionen dagegen in bestimmten Registern. Ferner erwarten sie den Library-Base-Pointer in Register a6. Betrachten wir eine Pragma-Anweisung von Aztec-C:

         #pragma amicall(SysBase,0xd2,FreeMem(a1,d0))

Dies weist den Compiler an, das erste Argument in Register a1 und das zweite in d0 zu laden. Ferner wird der Inhalt der Variablen SysBase in Register a6 geladen. Maxon-Pragmas sehen genauso aus, Dice- und SAS-Pragmas sind allerdings etwas komplizierter:

         #pragma libcall SysBase FreeMem d2 0902

Hier ist d2 (wie 0xd2 oben) der Library-Vektor-Offset (siehe nächstes Beispiel). Die letzte Ziffer ist die Zahl der Argumente, die davorstehende 0 ein Code für das Register mit dem Ergebnis und die davor stehenden Ziffern sind Codes für die Register mit den Argumenten in verkehrter Reihenfolge. (Die Codes bedeuten 0=d0, 1=d1, .., 8=a0, 9=a1, a=a2, ..)

Ein Kommando wie FreeMem(fib,sizeof(*fib); würde ein Compiler nun in folgenden Code übersetzen:

         move.l  _fib,a1
         move.l  260,d1	    ; sizeof(struct FileInfoBlock)
         move.l  _SysBase,a6
         jsr     -0xd2(a6)       ; 0xd2 = _LVOFreeMem

FreeMem in dieser Art aufzurufen ist kürzer und schneller als zunächst die Argumente auf den Stack zu legen und dann eine Funktion _FreeMem aufzurufen, die letzten Endes doch nur dasselbe tun und die Argumente vom Stack in dieselben Register laden würde.

Das Portierungsproblem der Pragmas umgeht man, indem man sie folgendermaßen in den eigenen Quelltext einbindet:

         /*	Lade den Funktionsprototyp. Dieser ist nicht vom	*/
         /*	verwendeten Compiler abhängig.				*/
         #include <clib/exec_protos.h>

         /*	Pragmas sind vom Compiler abhängig, aber wenigstens	*/
         /*	die Namen der Dateien mit Pragmas sind relativ		*/
         /*	einheitlich.						*/
         #ifdef AZTEC_C
         #include <pragmas/exec_lib.h>
         #endif
         #if defined(__SASC) || defined(_DCC) || defined(__MAXON__)
         #include <pragmas/exec_pragmas.h>
         #endif
         #ifdef __GNUC__
         #include <inline/exec_lib.h>
         #endif

Das obige Beispiel kann problemlos mit allen angegebenen Compilern verwendet werden und produziert optimalen Code.

Eine abschließende Frage bleibt allerdings: Wie bekommt man die Pragmas? Die meisten Compiler haben bereits fertige Pragmas im Lieferumfang. Allerdings hilft das nicht, wenn man z.B. eine neue Library benutzen möchte oder nur die Pragmas einer veralteten Version hat. In diesem Fall kann man die Pragmas selbst aus den sogenannten FD-Files erzeugen. Dazu haben die meisten Compiler ein Utility namens fd2pragma. (Das NDU hat z.B. ein Directory namens FD, in dem die FD-Files aller Libraries und Devices des OS enthalten sind. see Include-Dateien) Es gibt auch ein frei kopierbares fd2pragma, das Pragmas für Aztec, Dice, SAS und Maxon sowie LVO-Files für den Aztec-Assembler und eventuelle Tag-Versionen produziert. (Aminet, dev/misc/fd2pragma2_0.lha oder auf den Fish-CDs)

Für Pragmas unter dem gcc siehe Inline-Dateien.

Mein Compiler/Linker vermißt Symbole.
=====================================

Zunächst sollte man sich versichern, daß die Funktion tatsächlich fehlt: Z.B. Floating-Point-Funktionen befinden sich in einer speziellen Link-Library, die erst mit der Option -lm eingebunden wird. Ferner kann es eine fehlende Variable sein: Wenn man z.B. ohne es zu bemerken eine Intuition-Funktion benutzt, dann wird der Linker über das Fehlen eines Symbols IntuitionBase klagen. In diesem Fall muß man also lediglich das Folgende irgendwo im globalen Teil seines Quelltextes einbauen:

         struct Library *IntuitionBase;

(Und vergessen Sie nicht, die Library mit OpenLibrary() zu eröffnen und mit CloseLibrary() zu schließen!) :-)

Allerdings könnte die Funktion natürlich tatsächlich fehlen. Wenn man zum Beispiel nur die Version 2.0 der amiga.lib hat, dann fehlen etwa die Locale-Funktionen oder die Memory-Pool-Funktionen, obwohl sie prinzipiell verwendbar sind.  (Dieses Problem  betrifft vor allem Besitzer von Aztec-C, das seither nicht weiter unterstützt wird und von Dice, der manchmal etwas unvollständig ist. Ich besitze beide ..) Die einfachste (und beste) Lösung ist, das sogenannte NDU zu kaufen. See Include-Dateien. Wer nicht solange warten möchte, für den ist die Frage, welche Art von Funktion in seiner Link-Library fehlt:

  * Einfache Amiga-Library-Funktionen (z.B. exec/AllocPooled oder locale/OpenCatalogA) kann man mit Pragmas aufrufen und braucht dann lediglich Informationen über die Aufrufkonventionen (Library-Base, Library-Vektor-Offset und Argumentregister)

  * Tag-Funktionen sind meistens einfach Zwischenfunktionen, die ihre Argumente auf dem Stack erwarten und dann die eigentliche Library-Funktion aufrufen. Wenn man z.B. die Funktion dos/AllocDosObject, die eine Konstante und einen Zeiger auf ein Array als Argumente erwartet, nach der obigen Methode konstruiert hat, dann hat man damit auch ihre Stack-Variante! Dazu erzeugt man einfach die folgende Funktion:

              #include <clib/dos_protos.h>
              #include <pragmas/dos_pragmas.h>	/*  Evtl. anderer Name	*/

              void *AllocDosObjectTags(ULONG objtype, Tag tag1, ...)
              { return(AllocDosObject(objtype, (struct TagItem *) &tag1);
              }

     Mit fd2pragma kann das auch automatisch geschehen. See Pragmas.

  * Einige Funktionen bleiben aber noch übrig: Amiga.lib enthält nämlich auch Funktionen, die für sich selbst interessant sind, z.B. die BOOPSI-Funktionen (DoMethod, DoSuperMethod), die Memory-Pool-Funktionen (LibAllocPooled, LibCreatePool, die Ersatz für entsprechende 3.0-Funktionen sind) oder HookEntry, das sehr hilfreich bei der Programmierung von Hooks ist. Diese kann man nur durch entsprechende, disassemblierte und neu assemblierte oder compilierter Versionen ersetzen. Im AmigaFAQ-Archiv sind einige dieser Funktionen bereits enthalten.

Wie erfahre ich, was für Funktionen es gibt?
============================================

Wenn Sie sich über den Namen einer für einen bestimmten Zweck geeigneten Funktion im Unklaren sind, dann gibt es folgende Möglichkeiten:

  * In den Autodocs der verschiedenen Libraries findet man am Anfang eine alphabetisch sortierte Tabelle aller Funktionen, die die betreffende Library bietet. Im Hauptteil findet man dann eine detaillierte Spezifikation aller Funktionen. See Include-Dateien.

  * Die .FD-Dateien bieten eine sehr kompakte Übersicht über die Funktionen der diversen Libraries, sogar mit einer kurzen Angabe der Funktionsargumente. Wenn man schon grob weiß, wonach man sucht (z.B. nur die grobe Angabe der Argumente benötigt), dann findet man hier alle gewünschten Informationen. See Pragmas.

Dr. Peter Kittel, peterk@cbmger.de.so.commodore.com

     [file prog-gcc-g.texinfo not included]